package com.tax.infrastructure.extension;

import java.util.function.Consumer;
import java.util.function.Function;

/**
 * duandehui
 */
public abstract class AbstractExtensionComponentExecutor {

    /**
     * Execute extension with Response
     *
     * @param targetClz
     * @param bizScenario
     * @param exeFunction
     * @param <R>         Response Type
     * @param <T>         Parameter Type
     */
    public <R, T> R execute(Class<T> targetClz, BizScenario bizScenario, Function<T, R> exeFunction) {
        T component = locateComponent(targetClz, bizScenario);
        return exeFunction.apply(component);
    }

    public <R, T> R execute(ExtensionCoordinate extensionCoordinate, Function<T, R> exeFunction) {
        return execute((Class<T>) extensionCoordinate.getExtensionPointClass()
                , extensionCoordinate.getBizScenario(), exeFunction);
    }

    /**
     * @param targetClz
     * @param bizScenario
     * @param exeFunction
     * @param <T>         Parameter Type
     */
    public <T> void executeVoid(Class<T> targetClz, BizScenario bizScenario, Consumer<T> exeFunction) {
        T component = locateComponent(targetClz, bizScenario);
        exeFunction.accept(component);
    }

    public <T> void executeVoid(ExtensionCoordinate extensionCoordinate, Consumer<T> exeFunction) {
        executeVoid(extensionCoordinate.getExtensionPointClass(),extensionCoordinate.getBizScenario(),exeFunction);
    }

    public abstract <C> C locateComponent(Class<C> targetClz, BizScenario bizScenario);
}
